通过实战篇:预缓存可知,在安装阶段将资源进行缓存以便 Service Worker 变为可用后可直接从本地缓存中获取资源的能力,我们称之为预缓存。同时,我们已经对如何通过底层 API 来实现预缓存进行了详细说明,本章我们将学习如何使用 Workbox 来更高效地实现预缓存。
# 基本使用
Workbox通过调用workbox.precaching.precacheAndRoute来实现预缓存,比如:
workbox.precaching.precacheAndRoute([
'/styles/example.ac29.css',
{ url: '/index.html', revision: 'abcd1234' },
], {
ignoreURLParametersMatching: [/^utm_/],
directoryIndex: 'index.html',
cleanUrls: true,
urlManipulation: ({ url }) => {
return [URLObject];
}
});
workbox.precaching.precacheAndRoute 的参数依次为:
entries:数组类型,用于设置需要缓存的资源列表,其中每一项为字符串或格式为{ url: string, revision: string }的对象,使用规则为:如果名称中已包含资源的 hash 信息(即符合格式:[name].[hash].[ext]),则优先使用字符串,否则使用对象且必须指定revision属性的值,以便更好地处理资源的更新。- options:对象类型,相关属性为:
ignoreURLParametersMatching:用于忽略请求中符合指定规则的查询参数,默认值为[/^utm_/],即忽略请求中以utm_开头的请求参数(比如:/about.html?utm_campaign=abcd将使用预缓存/about.html来进行响应)。directoryIndex:默认值为index.html,即以预缓存/index.html来响应/的请求cleanUrls:当无法从预缓存中获得请求的响应时,是否为请求添加.html的后缀(比如:/about将使用预缓存/about.html来进行响应),默认值为true。urlManipulation:有些时候,我们可能需要自行匹配请求所对应的预缓存对象,此时便可使用此选项。该选项接收一个格式为{ url: URL }的对象,返回值为数组,且每一项的值为URL对象。
通过
workbox.precaching.precacheAndRoute方法,我们无需处理install、activate及fetch事件便可为Service Worker添加预缓存处理能力,但如果我们对其所提供的默认更新机制(根据资源的 revision 值进行更新)或请求策略(缓存优先)不满意,可通过workbox.precaching.PrecacheController来自行处理install、activate及fetch事件,比如:
const precacheController = new workbox.precaching.PrecacheController();
precacheController.addToCacheList([
'/styles/example.ac29.css',
{ url: '/index.html', revision: 'abcd1234' },
]);
self.addEventListener('install', (event) => {
event.waitUntil(precacheController.install());
});
self.addEventListener('activate', (event) => {
event.waitUntil(precacheController.activate());
});
self.addEventListener('fetch', (event) => {
const cacheKey = precacheController.getCacheKeyForURL(event.request.url);
event.respondWith(caches.match(cacheKey).then(...));
});
# 自动生成预缓存资源列表
在实战篇:预缓存中,我们通过实现 webpack 插件 SWFilePlugin 来自动生成预缓存资源列表,Workbox 也为我们提供了相关插件 workbox-webpack-plugin,主要包含:
GenerateSW:根据配置为我们自动生成 Service Worker 脚本,主要适用于进行预缓存及简单的运行时缓存处理,使用方法如下:
const { GenerateSW } = require('workbox-webpack-plugin');
module.exports = {
//... 其他配置
plugins: [
//... 其他插件
new GenerateSW({
swDest: 'sw.js',
importWorkboxFrom: 'local'
})
]
};
InjectManifest:生成预缓存列表并将其附加到已有的Service Worker脚本中去,适用于想要使用推送通知或更复杂的具有个性化定制功能的场景,使用方法如下:
const { InjectManifest } = require('workbox-webpack-plugin');
module.exports = {
//... 其他配置
plugins: [
//... 其他插件
new InjectManifest({
swSrc: './client/sw.js',
swDest: 'sw.js',
importWorkboxFrom: 'local'
})
]
};
由于
InjectManifest只会在已有的Service Worker脚本头部添加以下类似代码:
importScripts("/precache-manifest.6f5c74667aebc611e98f1f6384c686f4.js", "/workbox-v4.3.1/workbox-sw.js");
workbox.setConfig({modulePathPrefix: "/workbox-v4.3.1"});
因此我们需要在已有的
Service Worker脚本中自行调用workbox.precaching.precacheAndRoute方法,相关代码如下:
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
# 总结
本章我们首先对
workbox.precaching.precacheAndRoute方法的使用进行了详细介绍,利用该方法仅需要通过简单配置便能为 Service Worker 添加预缓存处理能力,然后我们对workbox.precaching.PrecacheController的使用进行了说明,它为我们自行控制预缓存的更新及访问策略提供了可能,最后我们讨论了如何使用GenerateSW和InjectManifest插件来自动生成预缓存资源列表。
完成了预缓存的学习,下一章,我们将对路由配置进行讨论。